package com.copd.config;

import com.copd.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

@Component
public class JwtRequestFilter extends OncePerRequestFilter {
    private static final Logger logger = LoggerFactory.getLogger(JwtRequestFilter.class);

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        final String authorizationHeader = request.getHeader("Authorization");
        logger.debug("Authorization header: {}", authorizationHeader);

        String username = null;
        String jwt = null;
        Integer userId = null;

        try {
            if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
                jwt = authorizationHeader.substring(7);
                logger.debug("Extracted JWT token: {}", jwt);
                
                if (jwt != null && !jwt.isEmpty()) {
                    username = jwtUtil.extractUsername(jwt);
                    logger.debug("Extracted username from token: {}", username);
                    
                    userId = jwtUtil.getUserIdFromToken(jwt);
                    logger.debug("Extracted userId from token: {}", userId);
                    
                    if (userId != null) {
                        request.setAttribute("doctorId", userId);
                        request.setAttribute("userId", userId);
                        logger.debug("User ID stored in request attributes: {}", userId);
                    }
                }
            }

            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                logger.debug("Loaded user details for username: {}", username);

                if (jwtUtil.validateToken(jwt, userDetails.getUsername())) {
                    // 确保所有用户都有基本的患者访问权限
                    Collection<?> existingAuthorities = userDetails.getAuthorities();
                    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                    
                    // 添加现有权限
                    existingAuthorities.forEach(auth -> {
                        authorities.add(new SimpleGrantedAuthority(auth.toString()));
                    });
                    
                    // 添加基本的患者管理权限
                    List<String> patientPermissions = Arrays.asList(
                        "patient:view", "patient:add", "patient:edit", "patient:delete"
                    );
                    
                    for (String permission : patientPermissions) {
                        if (!authorities.contains(new SimpleGrantedAuthority(permission))) {
                            authorities.add(new SimpleGrantedAuthority(permission));
                        }
                    }
                    
                    UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                            userId != null ? userId : userDetails, null, authorities);
                    authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authToken);
                    logger.debug("Authentication token set in SecurityContext with userId: {} and authorities: {}", userId, authorities);
                } else {
                    logger.warn("Token validation failed for user: {}", username);
                }
            }
        } catch (Exception e) {
            logger.error("Error processing JWT token: {}", e.getMessage(), e);
        }

        chain.doFilter(request, response);
    }
} 